﻿using HWInfo.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace HWInfo
{
    internal class HardwareInfoBase
    {
        #region 读取和执行方法
        /// <summary>
        /// 执行命令
        /// </summary>
        /// <param name="cmd">命令执行文件</param>
        /// <param name="args">命令参数</param>
        /// <returns></returns>
        internal static Process StartProcess(string cmd, string args)
        {
            ProcessStartInfo processStartInfo = new(cmd, args)
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardError = true,
                RedirectStandardInput = true,
                RedirectStandardOutput = true
            };

            return Process.Start(processStartInfo);
        }

        /// <summary>
        /// 执行命令并读取返回结果
        /// </summary>
        /// <param name="cmd">命令执行文件</param>
        /// <param name="args">命令参数</param>
        /// <returns></returns>
        internal static string ReadProcessOutput(string cmd, string args)
        {
            try
            {
                using Process process = StartProcess(cmd, args);
                
                using StreamReader streamReader = process.StandardOutput;
                process.WaitForExit();

                return streamReader.ReadToEnd().Trim();
            }
            catch
            {
                OSPlatform
                return string.Empty;
            }
        }

        internal static string Execute(string command, int seconds)
        {
            string output = ""; //输出字符串  
            if (command != null && !command.Equals(""))
            {
                var escapedArgs = command.Replace("\"", "\\\"");

                Process process = new();
                ProcessStartInfo startInfo = new()
                {
                    FileName = "/bin/bash",
                    Arguments = $"-c \"{escapedArgs}\"",
                    UseShellExecute = false,//不使用系统外壳程序启动  
                    RedirectStandardInput = false,//不重定向输入  
                    RedirectStandardOutput = true, //重定向输出  
                    CreateNoWindow = true//不创建窗口
                };

                process.EnableRaisingEvents = true;
                process.StartInfo = startInfo;
                
                try
                {
                    
                    if (process.Start())//开始进程  
                    {
                        if (seconds == 0)
                        {
                            process.WaitForExit();//这里无限等待进程结束  
                        }
                        else
                        {
                            process.WaitForExit(seconds); //等待进程结束，等待时间为指定的毫秒  
                        }
                        //string error = process.StandardError.ReadToEnd();
                        //Console.WriteLine($"Err:{error}");
                        output = process.StandardOutput.ReadToEnd();//读取进程的输出  
                    }
                }
                catch
                {
                }
                finally
                {
                    if (process != null)
                        process.Close();
                }
            }
            return output;
        }

        /// <summary>
        /// 读取文本文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        internal static string TryReadFileText(string path)
        {
            try
            {
                return File.ReadAllText(path).Trim();
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 读取文本文件返回行数组
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        internal static string[] TryReadFileLines(string path)
        {
            try
            {
                return File.ReadAllLines(path);
            }
            catch
            {
                return Array.Empty<string>();
            }
        }
        #endregion

        /// <summary>
        /// 序列化成Json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="indented"></param>
        /// <returns></returns>
        public static string ToJson(object obj, bool indented = false)
        {
            JsonSerializerSettings setting = new()
            {
                Formatting = indented ? Formatting.Indented : Formatting.None,
                StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
                NullValueHandling = NullValueHandling.Ignore
            };

            setting.Converters.Add(new IsoDateTimeConverter() 
            {
                DateTimeFormat = "yyyy-MM-dd HH:mm:ss"
            });

            return JsonConvert.SerializeObject(obj, setting);
        }

        public virtual List<NetworkAdapter> GetNetworkAdapterList()
        {
            List<NetworkAdapter> networkAdapterList = new();

            foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
            {
                NetworkAdapter networkAdapter = new()
                {
                    MACAddress = networkInterface.GetPhysicalAddress().ToString().Trim(),
                    Description = networkInterface.Description.Trim(),
                    Name = networkInterface.Name.Trim()
                };

                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    networkAdapter.Speed = (ulong)networkInterface.Speed;
                }

                foreach (UnicastIPAddressInformation addressInformation in networkInterface.GetIPProperties().UnicastAddresses)
                {
                    if (addressInformation.Address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        networkAdapter.IPAddressList.Add(addressInformation.Address);
                    }
                }

                networkAdapterList.Add(networkAdapter);
            }

            return networkAdapterList;
        }
    }
}
